/*
 *  Arrow
 *
 *  Created by David Giovannini on 1/5/07.
 *  Copyright 2007 Software by Jove. All rights reserved.
 *
 */
 
#ifndef SBJ_Arrow_TimerFeed_h
#define SBJ_Arrow_TimerFeed_h

#include "SBJ/Arrow/IPublisher.h"
#include "SBJ/Time/TimeInvoker.h"

#include <boost/noncopyable.hpp>

#include <memory>

namespace SBJ
{

namespace Arrow
{

class Message;

class TimerFeed : public IPublisher, private boost::noncopyable
{
public:
	typedef boost::shared_ptr< TimerFeed > Ptr;

	typedef TimeInvoker::Entry* Token;

	TimerFeed( void );

	virtual ~TimerFeed( void );

	template < typename MsgType >
	Token addMessage( MsgType& msg, double seconds, bool retroactive = true )
	{
		if ( seconds < 0.0 )
		{
			if ( retroactive )
			{
				seconds = 0;
			}
			else
			{
				return 0;
			}
		}
		TimeInvoker::Entry* entry = new MsgEntry< MsgType >( seconds, msg, m_router );
		m_invoker.addEntry( entry );
		return entry;
	}

	void cancelMessage( Token token );
	
	virtual bool start( void );
	
	virtual bool stop( bool join = true );
	
	virtual bool addRouter( const IRouter::Ptr& router );
	
	virtual bool removeRouter( const IRouter::Ptr& router );

private:
	template < typename MsgType >
	class MsgEntry : public TimeInvoker::Entry
	{
	public:
		MsgEntry( double interval, MsgType& msg, const IRouter::Ptr& router )
		: TimeInvoker::Entry( interval )
		, m_msg( msg )
		, m_router( router )
		{
		}
	private:
		virtual bool execute( void )
		{
			m_router->onMessage( m_msg );
			return false;
		}

		MsgType m_msg;
		IRouter::Ptr m_router;
	};

	IRouter::Ptr m_router;
	TimeInvoker m_invoker;
};

}

}

#endif